/*
 * Copyright 2007 - The JDPF Project Team (http://www.jdpf.org) 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */
package org.jdpf.core.plugins.parameters;


import java.text.ParseException;
import java.util.StringTokenizer;

public class ParamValidationParser {
	private String expression;

	public ParamValidationParser(String expression){
		this.expression = expression;
	}

	public boolean checkValue(Object value) throws Exception {
		char op = expression.charAt(0);
		boolean flag = false;
		if(expression.startsWith("{") && expression.endsWith("}")){
			flag = isInSet(value);
		}
		else if(op == '>'){
			double val=toDouble(value);
			flag = isGreaterThan(val);
		}
		else if(op == '<'){
			double val=toDouble(value);
			flag = isLowerThan(val);
		}

		return flag;
	}

	private boolean isInSet(Object value) {
		expression=expression.substring(1, expression.length()-1);
		StringTokenizer st=new StringTokenizer(expression,",");
		boolean flag=true;
		String val=value.toString().toLowerCase();
		while(st.hasMoreTokens()&&flag){
			flag=flag&&!(st.nextToken()).toLowerCase().equals(val);
		}
		return !flag;
	}

	private double toDouble(Object value) {
		Double d=null;
		if (value instanceof Integer) {
			d = ((Integer) value).doubleValue();
		}else if(value instanceof Float){
			d = ((Float) value).doubleValue();
		}else if(value instanceof Double){
			d = (Double)value;
		}
		return d.doubleValue();
	}

	private boolean isGreaterThan(double value) throws Exception{
		boolean flag = false;
		expression = expression.substring(1);
		int index = expression.indexOf('<');
		if(index != -1){
			String valueStr = expression.substring(0,index);
			Double a=Double.parseDouble(valueStr);
			try {
				flag = value > a;
			} catch (NumberFormatException e) {
				throw new ParseException("Error in parsing",1);
			}
			expression = expression.substring(index);
			Double d=Double.parseDouble(expression.substring(1));
			if(d-a>0){
				flag = flag&&isLowerThan(value);
			}else{
				flag = flag||isLowerThan(value);
			}
			    
		}
		else {
			try {
				flag = value > Double.parseDouble(expression);
			} catch (NumberFormatException e) {
				throw new ParseException("Error in parsing",1);
			}
		}

		return flag;
	}

	private boolean isLowerThan(double value) throws Exception{
		boolean flag = false;
		expression = expression.substring(1);
		int index = expression.indexOf('>');
		if(index != -1){
			String valueStr = expression.substring(0,index);
			Double a=Double.parseDouble(valueStr);
			try {
				flag = value < a;
			} catch (NumberFormatException e) {
				throw new ParseException("Error in parsing",1);
			}
			expression = expression.substring(index);
			Double d=Double.parseDouble(expression.substring(1));
			if(d-a<0){
				flag = flag&&isGreaterThan(value);
			}    
		}
		else {
			try {
				flag = value < Double.parseDouble(expression);
			} catch (NumberFormatException e) {
				throw new ParseException("Error in parsing",1);
			}
		}

		return flag;
	}
}
